package ldh.im.fxgui.pane;

import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import javafx.scene.text.TextFlow;
import javafx.stage.Popup;
import ldh.im.dto.enums.MessageType;
import ldh.im.fxbase.data.pojo.ImMessage;
import ldh.im.fxbase.data.pojo.ImUser;
import ldh.im.fxbase.util.ImCacheFactory;
import ldh.im.fxbase.util.ParamUtil;
import ldh.im.fxbase.util.RegionUtil;
import ldh.im.fxgui.controller.sub.ImUserMessagePopupController;
import ldh.im.fxgui.component.message.MessageHandler;
import org.controlsfx.control.PopOver;

public abstract class BaseMessagePane implements MessagePane {

    protected MessageHandler messageHandler;

    public Node createViewPane(MessageHandler messageHandler, ImMessage imMessage, boolean isReceive) {
        this.messageHandler = messageHandler;
        Node node = createPane(imMessage, isReceive, false);
        node.getStyleClass().add("message-item");
        return node;
    }

    @Override
    public Node createRefPane(ImMessage imMessage, boolean isReceive) {
        TextFlow textFlow = new TextFlow();
        TextAlignment textAlignment = TextAlignment.LEFT; //isReceive ? TextAlignment.LEFT : TextAlignment.RIGHT;
        textFlow.setTextAlignment(textAlignment);

        ImUser fromUser = imMessage.getFromImUser();
        if (fromUser == null) {
            fromUser = ImCacheFactory.getInstance().getUser(imMessage.getFromUserId());
        }

        if (imMessage.isGroup()) {
            Text fromUserText = new Text(fromUser.getUserName() + "：");
            fromUserText.setTextOrigin(VPos.TOP);
            fromUserText.setTextAlignment(textAlignment);

            textFlow.getChildren().add(fromUserText);
        }

        Node node = createPane(imMessage, isReceive, true);
        // 设置text的wrapWidth
        if (node instanceof Text) {
            ((Text) node).setWrappingWidth(ParamUtil.MESSAGE_WIDTH);
        } else if (node instanceof TextFlow) {
            for (Node cn : ((TextFlow) node).getChildren()) {
                if (cn instanceof Text) {
                    ((Text) cn).setWrappingWidth(ParamUtil.MESSAGE_WIDTH);
                }
            }
        }
        textFlow.getChildren().add(node);

        Rectangle rectangle = new Rectangle();
        textFlow.heightProperty().addListener(l->{
            rectangle.setHeight(textFlow.getHeight());
        });
        textFlow.widthProperty().addListener(l->{
            rectangle.setWidth(textFlow.getWidth()-10);
        });
        node.setClip(rectangle);

        if (imMessage.getMessageType() == MessageType.Text || imMessage.getMessageType() == MessageType.RichText ||
            imMessage.getMessageType() == MessageType.Url) {
            buildPopOver(textFlow, imMessage, isReceive);
        }
        return textFlow;
    }

    @Override
    public Node createCollectPane(ImMessage imMessage) {
        Node node = createRefPane(imMessage, true);
        if (node instanceof TextFlow) {
            TextFlow textFlow = (TextFlow) node;
            if (textFlow.getChildren().size() > 1) {
                textFlow.getChildren().remove(0);
            }

            if (textFlow.getChildren().size() > 0) {
                Node tnode = textFlow.getChildren().get(0);
                if (tnode instanceof StackPane) {
                    StackPane stackPane = (StackPane) tnode;
                    if (stackPane.getChildren().size() > 0) {
                        Node cnode = stackPane.getChildren().get(0);
                        if(cnode instanceof ImageView) {
                            ImageView imageView = (ImageView) cnode;
                            if(imageView.getFitHeight() == ParamUtil.MESSAGE_REF_HEIGHT) {
                                imageView.setFitHeight(100);
                            }
                        }
                    }
                }
            }
        }
        return node;
    }

    public abstract Node createPane(ImMessage imMessage, boolean isReceive, boolean isRef);

    protected void buildPopup(Node node, ImMessage message) {
        if (messageHandler == null) return;
        Popup popup = new Popup();
        popup.setAutoHide(true);
        node.setOnMousePressed(e->{
            RegionUtil.FxmlBean<VBox, ImUserMessagePopupController> fxmlBean = RegionUtil.loadFxmlBean(this.getClass().getResource("/fxml/sub/ImUserMessagePopup.fxml"));
            popup.getContent().add(fxmlBean.getNode());
            fxmlBean.getController().setMessage(message);
            fxmlBean.getController().setMessageHandler(messageHandler);
            fxmlBean.getController().setPopup(popup);

            if (!e.isPrimaryButtonDown()) {
                ((ImUserMessagePopupController)popup.getUserData()).rebuild();
                popup.show(node, e.getScreenX(), e.getScreenY());
            }
        });
    }

    protected void buildPopOver(Node node, ImMessage message, boolean isReceive) {
        PopOver popOver = new PopOver();
        popOver.setTitle("引用消息内容");
        popOver.setMinWidth(200);
        popOver.setAnimated(true);
        popOver.setDetachable(false);
        double offset = -10;
        if (isReceive) {
            popOver.setArrowLocation(PopOver.ArrowLocation.LEFT_CENTER);
        } else {
            popOver.setArrowLocation(PopOver.ArrowLocation.RIGHT_CENTER);
            offset = -15;
        }

        Node refNode = MessagePaneEnum.getByMessageType(message.getMessageType()).getMessagePane().createViewPane(null, message, false);
        refNode.setStyle("-fx-padding: 10px");
        popOver.setContentNode(refNode);

        double offsetValue = offset;
        node.setOnMouseClicked(e->{
            if (popOver.isShowing()) return;
            popOver.show(node, offsetValue);
        });
    }

    public void reset() {}

    public void update() {}

    public void dispose() {}
}
